package org.flowers.unbeaten.controller;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.impl.util.CollectionUtil;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.runtime.ProcessInstanceQuery;
import org.activiti.engine.task.Task;
import org.flowers.unbeaten.util.DataResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @description
 * @author RyanWang
 * @date 2021-08-02 10:43:10
 * @version 1.0
 */
@Api(tags = "流程引擎-流程定义")
@Slf4j
@RestController
@RequestMapping("/process/processDefinition")
public class ProcessDefinitionController {

    @Autowired
    private TaskService taskService;

    @Autowired
    private RuntimeService runtimeService;

    @Autowired
    private RepositoryService repositoryService;

    /**
     * 获取流程定义列表数据
     * @param pageEntity
     * @return
     */
//    @PostMapping("/list")
//    @ApiOperation("获取流程定义数据列表")
//    public PageResult list(@RequestBody PageEntity pageEntity) {
//        ProcessDefinitionQuery processDefinitionQuery = repositoryService.createProcessDefinitionQuery();
//        if (StringUtils.isNotBlank(pageEntity.getSearchKey())) {
//            processDefinitionQuery.processDefinitionNameLike(pageEntity.getSearchKey());
//        }
//
//        List<ProcessDefinition> processDefinitionList = processDefinitionQuery.orderByProcessDefinitionVersion().asc().listPage(pageEntity.start(), pageEntity.end());
//
//        List<ProcessDefinitionVo> list = new ArrayList<>();
//        if (!CollectionUtils.isEmpty(processDefinitionList)) {
//            processDefinitionList.forEach(processDefinition -> {
//                ProcessDefinitionVo processDefinitionVo = new ProcessDefinitionVo();
//                processDefinitionVo.setId(processDefinition.getId())
//                        .setName(processDefinition.getName())
//                        .setVersion(processDefinition.getVersion())
//                        .setKey(processDefinition.getKey())
//                        .setBpmn(processDefinition.getResourceName())
//                        .setPng(processDefinition.getDiagramResourceName())
//                        .setDeploymentId(processDefinition.getDeploymentId());
//                list.add(processDefinitionVo);
//            });
//        }
//
//        // 数据总条数
//        long count = processDefinitionQuery.orderByProcessDefinitionVersion().asc().count();
//
//        return pageResult(list, count);
//    }
//
//    /**
//     * 启动流程
//     * @param vo
//     * @return
//     */
//    @PostMapping("/startUp")
//    @ApiOperation(value = "根据流程部署ID启动流程")
//    public DataResult startUp(@RequestBody ProcessStartUpVo vo) {
//        ProcessInstance processInstance;
//        try {
//            if (StringUtils.isNotBlank(vo.getProcessKey())) {
//                processInstance = runtimeService.startProcessInstanceByKey(vo.getProcessKey());
//            } else {
//                processInstance = runtimeService.startProcessInstanceById(vo.getProcessInstanceId());
//            }
//            Task task = taskService.createTaskQuery().processInstanceId(processInstance.getProcessInstanceId()).singleResult();
//            if (StringUtils.isNotBlank(vo.getAssignee())) {
//                // 保存当前节点处理人
//                task.setAssignee(vo.getAssignee());
//                taskService.claim(task.getId(), vo.getAssignee());
//            }
//            return DataResult.getResult(200, "流程启动成功");
//        } catch (Exception e) {
//            log.error("根据流程key启动流程,异常:{}", e);
//            return DataResult.getResult(-1, "流程启动失败");
//        }
//    }

    /**
     * 根据部署ID删除流程
     * @param deploymentId
     * @return
     */
    @DeleteMapping("/deleteProcess/{deploymentId}")
    @ApiOperation(value = "根据部署ID删除流程")
    public DataResult deleteProcess(@PathVariable String deploymentId) {
        try {
            /**
             * 不带级联的删除：只能删除没有启动的流程，如果流程启动，就会抛出异常
             */
            repositoryService.deleteDeployment(deploymentId, true);
            return DataResult.getResult(200, "删除成功");
        } catch (Exception e) {
            log.error("根据部署ID删除流程,异常:{}", e);
            return DataResult.getResult(-1, "删除失败");
        }
    }

    /**
     * 根据流程key查询流程实例
     * @param processDefinitionKey
     * @return
     */
    @GetMapping("/getProcessInstance/processDefinitionKey")
    @ApiOperation(value = "根据流程key查询流程实例")
    public DataResult getProcessInstance(@PathVariable String processDefinitionKey) {
        try {
            ProcessInstanceQuery processInstanceQuery = runtimeService.createProcessInstanceQuery();
            List<ProcessInstance> list = processInstanceQuery.processDefinitionKey(processDefinitionKey).list();
            return DataResult.getResult(200, "查询成功", list);
        } catch (Exception e) {
            log.error("根据流程key查询流程实例,异常:{}", e);
            return DataResult.getResult(-1, "查询失败");
        }
    }

    /**
     * 根据流程ID查询流程实例
     * @param processId
     * @return
     */
    @GetMapping("/getProcessInstanceByProcessId/processId")
    @ApiOperation(value = "根据流程ID查询流程实例")
    public DataResult getProcessInstanceByProcessId(@RequestParam("processId") String processId) {
        try {
            ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceId(processId).singleResult();
            return DataResult.getResult(200, "查询成功", processInstance);
        } catch (Exception e) {
            log.error("根据流程ID查询流程实例,异常:{}", e);
            return DataResult.getResult(-1, "查询失败");
        }
    }

    /**
     * 根据流程实例ID删除流程实例
     * @param processId
     * @return
     */
    @DeleteMapping("/deleteProcessInstance/processId")
    @ApiOperation(value = "根据流程实例ID删除流程实例")
    public DataResult deleteProcessInstance(@PathVariable String processId) {
        try {
            runtimeService.deleteProcessInstance(processId, "删除" + processId);
            return DataResult.getResult(200, "删除成功");
        } catch (Exception e) {
            log.error("根据流程实例ID删除流程实例,异常:{}", e);
            return DataResult.getResult(-1, "删除失败");
        }
    }

    /**
     * 根据流程实例key删除流程实例
     * @param processDefinitionKey
     * @return
     */
    @DeleteMapping("/deleteProcessInstanceByKey/processDefinitionKey")
    @ApiOperation(value = "根据流程实例key删除流程实例")
    public DataResult deleteProcessInstanceByKey(@PathVariable String processDefinitionKey) {
        try {
            ProcessInstanceQuery processInstanceQuery = runtimeService.createProcessInstanceQuery();
            List<ProcessInstance> list = processInstanceQuery.processDefinitionKey(processDefinitionKey).list();
            return DataResult.getResult(200, "删除成功", list);
        } catch (Exception e) {
            log.error("根据流程实例key删除流程实例,异常:{}", e);
            return DataResult.getResult(-1, "删除失败");
        }
    }

    /**
     * 根据流程assignee查询当前人的个人任务
     * @param assignee
     * @return
     */
    @GetMapping("/getTaskByAssignee/assignee")
    @ApiOperation(value = "根据流程assignee查询当前人的个人任务")
    public DataResult getTaskByAssignee(@RequestParam("assignee") String assignee) {
        try {
            //指定个人任务查询
            List<Task> taskList = taskService.createTaskQuery().taskAssignee(assignee).list();
            if (CollectionUtil.isNotEmpty(taskList)) {
                List<Map<String, String>> resultList = new ArrayList<>();
                for (Task task : taskList) {
                    Map<String, String> resultMap = new HashMap<>();
                    // 任务ID
                    resultMap.put("taskID", task.getId());
                    // 任务名称
                    resultMap.put("taskName", task.getName());
                    // 任务的创建时间
                    resultMap.put("taskCreateTime", task.getCreateTime().toString());
                    // 任务的办理人
                    resultMap.put("taskAssignee", task.getAssignee());
                    // 流程实例ID
                    resultMap.put("processInstanceId", task.getProcessInstanceId());
                    // 执行对象ID
                    resultMap.put("executionId", task.getExecutionId());
                    // 流程定义ID
                    resultMap.put("processDefinitionId", task.getProcessDefinitionId());
                    resultList.add(resultMap);
                }
                return DataResult.getResult(200, "查询成功", resultList);
            } else {
                return DataResult.getResult(200, "查询成功", null);
            }
        } catch (Exception e) {
            log.error("根据流程assignee查询当前人的个人任务,异常:{}", e);
            return DataResult.getResult(-1, "查询失败");
        }
    }

    /**
     * 完成任务
     * @param taskId
     * @return
     */
    @GetMapping("/completeTask/{taskId}/{variables}")
    @ApiOperation(value = "完成任务")
    public DataResult completeTask(@PathVariable String taskId, @PathVariable boolean variables) {
        try {
            Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
            taskService.complete(taskId, (Map) (new HashMap<String, Boolean>() {{
                put("result", variables);
            }}));
            ProcessInstance instance = runtimeService.createProcessInstanceQuery().processInstanceId(task.getProcessInstanceId()).singleResult();
            if (instance == null) {

            }
            return DataResult.getResult(200, "完成任务成功", taskId);
        } catch (Exception e) {
            log.error("完成任务,异常:{}", e);
            return DataResult.getResult(-1, "完成任务失败");
        }
    }

    /**
     * 任务转办
     * @param taskId
     * @param userKey
     * @return
     */
    @PostMapping("turnTask")
    @ApiOperation(value = "任务转办", notes = "任务转办，把任务交给别人处理")
    public DataResult turnTask(@RequestParam("taskId") String taskId, @RequestParam("userKey") String userKey) {
        try {
            taskService.setAssignee(taskId, userKey);
            return DataResult.getResult(200, "完成任务成功", taskId);
        } catch (Exception e) {
            log.error("任务转办,异常:{}", e);
            return DataResult.getResult(-1, "完成任务失败");
        }
    }

}
